package xyz.paragon.product.controller;

import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import xyz.paragon.product.event.DeleteProductEvent;
import xyz.paragon.product.event.EventProcessor;
import xyz.paragon.product.persistence.domain.Product;
import xyz.paragon.product.persistence.service.ProductService;

import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@EnableBinding(EventProcessor.class)
public class ProductController {

    private final ProductService productService;
    private final EventProcessor eventProcessor;

    public ProductController(ProductService productService,
                             EventProcessor eventProcessor) {
        this.productService = productService;
        this.eventProcessor = eventProcessor;
    }

    @GetMapping(value = "")
    public ResponseEntity<List<Product>> findAll(@RequestParam Map<String, String> params) {

        List<Product> products = this.productService.findAll(params);

        return ResponseEntity.ok(products);
    }

    @GetMapping(value = "/{productId}")
    public ResponseEntity<?> findById(@PathVariable Long productId) {

        Product product = this.productService.findById(productId);

        return ResponseEntity.ok(product);
    }

    @PostMapping(value = "")
    public ResponseEntity<?> saveProduct(@RequestBody Product newProduct) {

        Product product = this.productService.save(newProduct);
        URI location = ServletUriComponentsBuilder
                .fromCurrentRequest()
                .path("/{productId}")
                .buildAndExpand(product.getId())
                .toUri();

        return ResponseEntity.created(location).body(product);
    }

    @PutMapping("/{productId}")
    public ResponseEntity<?> updateProduct(@PathVariable Long productId,
                                           @RequestBody Product updatedProduct) {

        Product product = this.productService.save(updatedProduct);

        return ResponseEntity.ok(product);
    }

    @DeleteMapping("/{productId}")
    public ResponseEntity<?> deleteProduct(@PathVariable Long productId) {

        this.productService.deleteById(productId);
        this.eventProcessor.deleteProductEventChannel().send(
                MessageBuilder.withPayload(new DeleteProductEvent(UUID.randomUUID().toString(), productId)).build());

        return ResponseEntity.ok("Product has been successfully removed.");
    }

}
